﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using Oracle.ManagedDataAccess.Client;

namespace Brilliant.ORM
{
    /// <summary>
    /// 数据访问对象
    /// </summary>
    public class Oracle : IDataProvider
    {
        private DBTrans dbTrans;

        public string ConnectionString { get; set; }

        public bool Transaction
        {
            get { return dbTrans == null ? false : true; }
        }

        public Oracle(string connectionString)
        {
            this.ConnectionString = connectionString;
        }

        public void BeginTransaction()
        {
            dbTrans = new DBTrans();
            dbTrans.Conn = new OracleConnection(ConnectionString);
            dbTrans.Conn.Open();
            dbTrans.Cmd = new OracleCommand();
            dbTrans.Cmd.Connection = dbTrans.Conn;
            dbTrans.Trans = dbTrans.Conn.BeginTransaction();
            dbTrans.Cmd.Transaction = dbTrans.Trans;
        }

        public void Commit()
        {
            dbTrans.Commit();
            dbTrans.Close();
            dbTrans = null;
        }

        public void Rollback()
        {
            dbTrans.Rollback();
            dbTrans.Close();
            dbTrans = null;
        }

        private OracleCommand PrepareCommand(OracleConnection conn, string cmdText, CommandType cmdType, IDataParameter[] parameters)
        {
            if (conn.State != ConnectionState.Open)
            {
                conn.Open();
            }
            OracleCommand cmd = new OracleCommand(cmdText, conn);
            cmd.CommandType = cmdType;
            if (parameters != null)
            {
                cmd.Parameters.Clear();
                cmd.Parameters.AddRange(parameters);
            }
            return cmd;
        }

        public DataSet ExecDataSet(SQL sql)
        {
            using (OracleConnection conn = new OracleConnection(ConnectionString))
            {
                OracleCommand cmd = PrepareCommand(conn, sql.CmdText, sql.CmdType, sql.Parameters);
                OracleDataAdapter da = new OracleDataAdapter(cmd);
                DataSet ds = new DataSet();
                da.Fill(ds);
                return ds;
            }
        }

        public IDataReader ExecDataReader(SQL sql)
        {
            OracleConnection conn = new OracleConnection(ConnectionString);
            OracleCommand cmd = PrepareCommand(conn, sql.CmdText, sql.CmdType, sql.Parameters);
            return cmd.ExecuteReader(CommandBehavior.CloseConnection);
        }

        public object ExecScalar(SQL sql)
        {
            using (OracleConnection conn = new OracleConnection(ConnectionString))
            {
                OracleCommand cmd = PrepareCommand(conn, sql.CmdText, sql.CmdType, sql.Parameters);
                return cmd.ExecuteScalar();
            }
        }

        public int ExecNonQuerry(SQL sql)
        {
            if (Transaction)
            {
                dbTrans.Cmd.CommandText = sql.CmdText;
                dbTrans.Cmd.CommandType = sql.CmdType;
                if (sql.Parameters != null)
                {
                    dbTrans.Cmd.Parameters.Clear();
                    dbTrans.Cmd.Parameters.AddRange(sql.Parameters);
                }
                return dbTrans.Cmd.ExecuteNonQuery();
            }
            else
            {
                using (OracleConnection conn = new OracleConnection(ConnectionString))
                {
                    OracleCommand cmd = PrepareCommand(conn, sql.CmdText, sql.CmdType, sql.Parameters);
                    return cmd.ExecuteNonQuery();
                }
            }
        }

        public int ExecTrans(List<SQL> sqlList)
        {
            int count = 0;
            try
            {
                BeginTransaction();
                foreach (SQL sql in sqlList)
                {
                    count += ExecNonQuerry(sql);
                }
                Commit();
            }
            catch
            {
                Rollback();
                count = 0;
            }
            return count;
        }

        public IDataParameter GetParameter(string parameterName, object value)
        {
            OracleParameter parameter = new OracleParameter();
            parameter.ParameterName = parameterName;
            parameter.Value = TypeMap.FilterNull(value);
            return parameter;
        }
    }
}
